﻿using System.Collections.Generic;

namespace Storyteller.Framework
{
	public class ScreenManager
	{
		public Game Game { get; protected set; }

		public ScreenManager(Game game)
		{
			Game = game;
		}

		public void Update(float deltaSeconds)
		{
			for(int i=0; i<screensToAdd.Count; i++)
			{
				screensToAdd[i].OnAdd();
			}
			
			screens.AddRange(screensToAdd);
			screensToAdd.Clear();

			GameScreen waitingScreen = null;
			bool hasFocus = true;
			bool foundExclusive = false;

			for (int i = screens.Count - 1; i >= 0; --i)
			{
				GameScreen gameScreen = screens[i];

				if (gameScreen.ScreenState == ScreenState.Waiting)
				{
					if (waitingScreen == null)
					{
						waitingScreen = gameScreen;
					}
					else
					{
						gameScreen.ExitScreen(false);
					}
				}
				else
				{
					if (gameScreen.IsExclusive)
					{
						if (foundExclusive)
							gameScreen.ExitScreen(true);
						else
							foundExclusive = true;
					}
				}

				gameScreen.Update(deltaSeconds, hasFocus);
				hasFocus = false;
			}

			foundExclusive = false;
			waitingScreen = null;
			
			for (int i = screens.Count - 1; i >= 0; i--)
			{
				if (screens[i].NeedsRemoved)
				{
					screens[i].OnRemove();
					screens.RemoveAt(i);
				}
			}

			foreach (GameScreen gameScreen in screens)
			{
				if (gameScreen.ScreenState == ScreenState.Waiting)
				{
					waitingScreen = gameScreen;
				}
				else if (gameScreen.IsExclusive)
				{
					foundExclusive = true;
				}
			}

			if (waitingScreen != null && !foundExclusive)
			{
				waitingScreen.Update(0, true);
			}
		}

		public void Draw()
		{
			foreach(GameScreen gameScreen in screens)
			{
				gameScreen.Draw();
			}
		}

		public void AddScreen(GameScreen gameScreen)
		{
			gameScreen.Reset();
			
			if (!gameScreen.IsExclusive)
				gameScreen.ScreenState = ScreenState.TransitionOn;
			else
				gameScreen.ScreenState = ScreenState.Waiting;

			screensToAdd.Add(gameScreen);
		}

		List<GameScreen> screens = new List<GameScreen>();
		List<GameScreen> screensToAdd = new List<GameScreen>();
	}
}
